package org.hhw.service.impl;

import com.alibaba.fastjson.JSONArray;
import org.hhw.cache.ICourseTypeCache;
import org.hhw.client.PageConfigClient;
import org.hhw.client.RedisClient;
import org.hhw.domain.CourseType;
import org.hhw.mapper.CourseTypeMapper;
import org.hhw.service.ICourseTypeService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author hhw
 * @since 2020-02-17
 */
@Service
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private CourseTypeMapper courseTypeMapper;
    //和mapper相似，mapper操作的是数据库的数据，而换成操作的是redis数据
    @Autowired
    private ICourseTypeCache courseTypeCache;
    @Autowired
    private PageConfigClient pageConfigClient;
    @Autowired
    private RedisClient redisClient;

    @Override
    public List<CourseType> treeData(long pid) {
        List<CourseType> courseTypes = courseTypeCache.getTreeData();
        if (courseTypes!=null && courseTypes.size()>0) {
            //直接返回
            System.out.println("拿到缓存cache");
            return courseTypes;
        } else {
            System.out.println("db");
            //否则先查询数据库，放入缓存后再返回
            //递归思想 每一个节点都会发一条sql
            //return treeDataRecursion(pid);
            //循环方案 一条sql
            List<CourseType> courseTypesOfDb = treeDataLoop(pid);
            //设置缓存
            courseTypeCache.setTreeDate(courseTypesOfDb);
            return courseTypesOfDb;
        }
    }

    @Override
    public void staticIndexPageInit() {
        //页面名称写死
        String pageName = "CourseSiteIndex";
        //需要一个保存到redis数据库的key
        String dataKey="CourseSiteIndex_data";
        List<CourseType> courseTypes = this.treeData(0L);
        //课程处理
        Map<String,Object> courseTypeSdata = new HashMap<>();
        courseTypeSdata.put("courseTypes",courseTypes);
        //职位
        //Map<String,Object> JobsTypeSdata = new HashMap<>();
        //JobsTypeSdata.put("jobTypes",courseTypes);
        redisClient.add(dataKey, JSONArray.toJSONString(courseTypeSdata)); //{courseTypes:[]}

        //3 调用方法模板+数据=静态页面
        pageConfigClient.staticPage(pageName,dataKey);
    }
    //获取面包屑
    @Override
    public List<Map<String, Object>> queryCrumbs(Long courseTypeId) {
        List<Map<String,Object>> result = new ArrayList<>();
        //通过courseTypeId获取CourseType,得到path，层次结构
        String path = courseTypeMapper.selectById(courseTypeId).getPath();
        path = path.substring(1, path.length() - 1);//层次1,2,3
        String[] paths = path.split("\\.");
        //对每个节点进行处理 Map
        for (String idStr : paths) {
            Map<String, Object> node = new HashMap<>();
            //表示自己
            CourseType owerCourseType = courseTypeMapper.selectById(Long.valueOf(idStr));
            node.put("owerCourseType", owerCourseType);
            //表示兄弟
            //获取父亲的所有儿子
            Long pid = owerCourseType.getPid();
            List<CourseType> allChildren = courseTypeMapper.selectList(new EntityWrapper<CourseType>().eq("pid", pid));
            //删除自己
            Iterator<CourseType> iterator = allChildren.iterator();
            while (iterator.hasNext()){
                CourseType type = iterator.next();
                //自己id为遍历出来的id
                if (owerCourseType.getId().intValue()==type.getId().intValue()){
                    iterator.remove();
                    break;
                }
            }
            node.put("otherCourseType", allChildren);
            result.add(node);
        }
        return result;
    }

    /**
     * 方式2循环方案 只查询一条数据
     * @param pid
     * @return
     */
    private List<CourseType> treeDataLoop(long pid){
        //查询所有节点
        List<CourseType> allNodes = courseTypeMapper.selectList(null);
        //查询父亲，建立id-node的集合
        Map<Long,CourseType> allNodeDto = new HashMap<>();
        for(CourseType courseType : allNodes){
            allNodeDto.put(courseType.getId(),courseType);
        }
        //关系
        List<CourseType> result = new ArrayList<>();
        for (CourseType courseType : allNodes) {
            //判断一节级节点直接放进result
            if(courseType.getPid().intValue()==0){
                result.add(courseType);
            }else {
                //不是一级节点，建立父子关系，把自己做父亲，一个儿子放进去
                //获取父亲
                Long pidTmp = courseType.getPid();
                //方式一 遍历循环 效率低
                /*
                for (CourseType courseType1 : allNodes) {
                    if (courseType1.getId() == pidTmp) {
                        //获取到父亲
                    }
                }*/
                //方式二：提前建立关系，直接获取
                CourseType parent = allNodeDto.get(pidTmp);
                //给父亲添加儿子
                parent.getChildren().add(courseType);
            }
        }
        return result;
    }
    /**
     * 通过父id查询儿子，有儿子就设置为自己的儿子，没有就返回
     * 自己调用自己
     * //返回条件
     * @param pid
     * @return
     */
    private List<CourseType> treeDataRecursion(long pid) {
        List<CourseType> children = courseTypeMapper
                .selectList(new EntityWrapper<CourseType>().eq("pid", pid));
        //返回条件
        if (children==null || children.size()<1){
            return null;
        }
        for (CourseType child : children) {
            //自己调用自己
            List<CourseType> cTmp = treeDataRecursion(child.getId());
            child.setChildren(cTmp);
        }

        return children;

    }

    //重写增删改-同步缓存

    @Override
    public boolean insert(CourseType entity) {

        courseTypeMapper.insert(entity);
        courseTypeCache.setTreeDate(treeDataLoop(0));
        staticIndexPageInit(); //静态化课程主页
        return true;
    }

    @Override
    public boolean deleteById(Serializable id) {
        courseTypeMapper.deleteById(id);
        courseTypeCache.setTreeDate(treeDataLoop(0));
        staticIndexPageInit(); //静态化课程主页
        return true;
    }

    @Override
    public boolean updateById(CourseType entity) {
        courseTypeMapper.updateById(entity);
        courseTypeCache.setTreeDate(treeDataLoop(0));
        staticIndexPageInit(); //静态化课程主页
        return true;
    }
}